package com.tomtop.core.utils;


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public final class Transfer{
	private static final Logger logger = LoggerFactory.getLogger(Transfer.class);
	/**
	 * 集合转集合.
	 * @param targetclasz
	 * @param list
	 * @return
	 */
	public final static <T> List<T>  form(Class<T> targetclasz,Iterable<?>  it,Object...params){
		List<T> result = new ArrayList<T>();
		if ( it == null) {
			return result;
		}
		Object[] _params=new Object[params.length+1];
		for (int i = 0; i < params.length; i++) {
			_params[i+1] = params[i];
		}
		for (Object item :  it) {
			if(item==null)continue;
			_params[0]=item;
			result.add(form(targetclasz,_params));
		}
		return result;
	}
	/**
	 * 类型转类型
	 * @param targetclasz
	 * @param params
	 * @return 都等于null 返回null,targetclasz==null 返回的也是null
	 */
	public final static  <T> T form(Class<T> targetclasz ,Object ... params){
		if(targetclasz==null||params[0]==null)
			{
				logger.warn("目标类型为空,或者原始类型为空");
				return null;
			}
		Class<?>[] classInput=new Class<?>[params.length];
		int nullnum=0;
		for (int i = 0; i < params.length; i++) {
			if(params[i]!=null)
				classInput[i]=params[i].getClass();
			else nullnum++;
		}
		if(nullnum!=0&&nullnum==params.length){
			logger.info("类{}初始化参数全部为null,返回null",targetclasz.getName());
			return null;
		}
		
		@SuppressWarnings("unchecked")
		Constructor<T>[] ms = (Constructor<T>[]) targetclasz.getConstructors();
		Constructor<T> constructor=null;
		
		constructors:for (Constructor<T> constructor_ : ms) {
			Class<?>[] classParam = constructor_.getParameterTypes();
			Class<?>[] mdcs = constructor==null?null:constructor.getParameterTypes();
			if(classParam.length!=classInput.length)
				continue;
			
			if(classInput==null||classInput.length==0){
				if(classParam.length==0)
				{
					constructor=constructor_;
				}
				break;
			}else{
				for (int i = 0; i < classParam.length; i++) {
					if(classInput[i]!=null&&(
							!classParam[i].isAssignableFrom(classInput[i])||
							(mdcs!=null&&!mdcs[i].isAssignableFrom(classParam[i])))){
						continue constructors;
					} 
				}
				constructor=constructor_;
			}
		}
		try {
			if(constructor==null){
				String classnames="";
				for (Class<?> classname : classInput) {
					classnames+=classname==null?","+Object.class.getName():","+classname.getName();
				}
				classnames=classnames.substring(1);
				logger.error("类转化时没有找到匹配的初始化方法{} {}",targetclasz.getName(),classnames);
				return null;
			}
			T newInstance =  constructor.newInstance(params);
			return newInstance;
		} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			logger.error("调用方法内异常 目标类型:{}  初始化参数个数{} msg {}",targetclasz,params.length,e.getMessage(),e);
			return null;
//			throw new RuntimeException(e);
		}
	}
	public final static <T> Object executeMethod(T t,String methodName,Object ... params){
		Class<?>[] parameterTypes=new Class<?>[params.length];
		for (int i = 0; i < params.length; i++) {
			if(params[i]!=null)
				parameterTypes[i]=params[i].getClass();
			else 
				parameterTypes[i]=Object.class;
		}
		Method method=null;
		try {
			method = t.getClass().getMethod(methodName, parameterTypes);
		} catch (NoSuchMethodException | SecurityException e) {
			String classnames="";
			for (Class<?> classname : parameterTypes) {
				classnames+=classname==null?","+Object.class.getName():","+classname.getName();
			}
			classnames=classnames.substring(1);
			logger.error("没有找到这个方法"+t.getClass().getName()+".methodName("+classnames+")",e);
			return null;
		}
		try {
			return method.invoke(t, params);
		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			logger.error("调用方法内异常 目标类型:{}  初始化参数个数{} msg {}",t.getClass(),params.length,e.getMessage());
			throw new RuntimeException(e);
		}
	}
}
